package com.scs.application.core.utils;

import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.*;

/**
 * @program: fortec-mscm-parent
 * @description:
 **/
public class ZipUtils {

    /**
     * 使用zip进行压缩
     *
     * @param str 压缩前的文本
     * @return 返回压缩后的文本
     */
    public static final String zip(String str) {
        if (str == null)
            return null;
        byte[] compressed;
        String compressedStr = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ZipOutputStream zout = new ZipOutputStream(out)) {

            zout.putNextEntry(new ZipEntry("0"));
            zout.write(str.getBytes("utf-8"));
            zout.closeEntry();
            compressed = out.toByteArray();
            compressedStr = new String(new Base64().encode(compressed), "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
            compressed = null;
        }
        return compressedStr.replace("\n", "");
    }


    /**
     * 使用zip进行解压缩
     *
     * @param str 压缩后的文本
     * @return 解压后的字符串
     */
    public static final String unzip(String str) {
        if (str == null) {
            return null;
        }

        ByteArrayOutputStream out = null;
        ByteArrayInputStream in = null;
        ZipInputStream zin = null;
        String decompressed = null;
        try {
            byte[] compressed = new Base64().decode(str.getBytes("utf-8"));
            out = new ByteArrayOutputStream();
            in = new ByteArrayInputStream(compressed);
            zin = new ZipInputStream(in);
            zin.getNextEntry();
            byte[] buffer = new byte[1024];
            int offset = -1;
            while ((offset = zin.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString("utf-8");
        } catch (IOException e) {
            decompressed = null;
        } finally {
            if (zin != null) {
                try {
                    zin.close();
                } catch (IOException e) {
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }
        return decompressed;
    }

    /**
     * 使用gzip进行压缩，并将压缩后的数据BASE64编码
     */
    public static String gzipAndBase64(String primStr) {
        if (primStr == null || primStr.length() == 0) {
            return primStr;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = null;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(primStr.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Base64.encodeBase64String(out.toByteArray());
    }

    /**
     * BASE64解码后，gzip解压缩
     */
    public static String unBase64AndUnGzip(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }

        byte[] compressed = null;
        compressed = Base64.decodeBase64(compressedStr);

        String decompressed = null;
        try (
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ByteArrayInputStream in = new ByteArrayInputStream(compressed);
                GZIPInputStream ginzip = new GZIPInputStream(in);
        ) {
            byte[] buffer = new byte[1024];
            int offset = -1;
            while ((offset = ginzip.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return decompressed;
    }

}
